home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 22
/
Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso
/
Aminet
/
util
/
misc
/
cookietool.lha
/
cookietool
/
strstuff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-20
|
5KB
|
213 lines
/*========================================================================*\
| File: strstuff.c Date: 20 Sep 1997 |
*------------------------------------------------------------------------*
| Some string functions, similar to those from the standard library |
| in <string.h>, but more flexible. |
| You must call str_setup() before using any of these functions !!! |
| |
\*========================================================================*/
#include <stddef.h>
#include <stdio.h>
#include "strstuff.h"
UBYTE to_upper[ 256 ]; /* conversion table */
int is_space[ 256 ]; /* lookup table */
int bordermode, case_sense;
/*
* Set up a to_upper[] table that can convert all national characters from
* the ISO 8859-1/ECMA 94 charset to uppercase, not only 'a'-'z'.
* Depending on the global variable <case_sense> this table may just as
* well do nothing at all.
* Similarly, the is_space[] table which is built here may call anything
* but alphanumerics a 'space', depending on the setting of <bordermode>.
*/
void str_setup( int bm, int cs )
{
int c, d;
bordermode = bm;
case_sense = cs; /* set global variables */
for( c = 0; c < 256; c++ )
{
to_upper[ c ] = c;
is_space[ c ] = ( bordermode < 2 || (c & 0x7f) <= ' ' );
}
for( c = 'a'; c <= 'z'; c++ )
{
d = c + 'A' - 'a';
to_upper[ c ] = d;
is_space[ c ] = 0;
is_space[ d ] = 0;
}
for( c = '0'; c <= '9'; c++ )
{
is_space[ c ] = 0;
}
for( c = 224; c < 256; c++ )
if( c != 247 )
{ /* 247 is the division sign -:- */
d = c - 32;
is_space[ c ] = 0;
is_space[ d ] = 0;
if( c != 255 ) /* and don't convert '"y' to 'ss' : ) */
to_upper[ c ] = d;
}
if( case_sense ) /* destroy the to_upper[] table again */
for( c = 0; c < 256; c++ )
to_upper[ c ] = c;
is_space[ 0 ] = 0; /* important, will be taken advantage of! */
}
/*
* str_cmp() will work like strcmp() if( case_sense && bordermode == 3 ),
* but can change its behaviour depending on those variables.
* Will also indicate by special (but legal) return values if <s> was an
* abbreviation of <t> or vice versa.
*/
int str_cmp( UBYTE *s, UBYTE *t )
{
if( bordermode < 3 )
{ /* modes where number of 'spaces' doesn't count */
while( is_space[ *s ] )
s++; /* advance to first word */
while( is_space[ *t ] )
t++;
while( to_upper[ *s ] == to_upper[ *t ] )
{
if( *s == '\0' )
return 0;
s++;
t++;
if( !bordermode || (is_space[ *s ] && is_space[ *t ]) )
{
/* both at the end of a word OR in sloppy bordermode */
while( is_space[ *s ] )
s++; /* skip the spaces */
while( is_space[ *t ] )
t++;
}
}
}
else
{
while( to_upper[ *s ] == to_upper[ *t ] )
{
if( *s == '\0' )
return 0;
s++;
t++;
}
}
if( *s == '\0' )
return STR_SHORTER;
else if( *t == '\0' )
return STR_LONGER;
else
return( to_upper[ *s ] - to_upper[ *t ] );
}
/*
* The same as str_cmp(), but will only compare up to <n> characters.
* (Only two lines of code are different.)
*/
int strn_cmp( UBYTE *s, UBYTE *t, size_t n )
{
if( bordermode < 3 )
{
while( is_space[ *s ] )
s++;
while( is_space[ *t ] )
t++;
while( to_upper[ *s ] == to_upper[ *t ] )
{
if( --n == 0 || *s == '\0' )
return 0; /* that's the difference */
s++;
t++;
if( !bordermode || (is_space[ *s ] && is_space[ *t ]) )
{
while( is_space[ *s ] )
s++;
while( is_space[ *t ] )
t++;
}
}
}
else
{
while( to_upper[ *s ] == to_upper[ *t ] )
{
if( --n == 0 || *s == '\0' )
return 0; /* and here once more */
s++;
t++;
}
}
if( *s == '\0' )
return STR_SHORTER;
else if( *t == '\0' )
return STR_LONGER;
else
return( to_upper[ *s ] - to_upper[ *t ] );
}
/*
* Find a copy of t in s, like strstr( )does.
* Note that bordermode has NO effect here!
*/
UBYTE *str_str( UBYTE *s, UBYTE *t )
{
int c;
while( *s )
{
c = str_cmp( s, t );
if( c == 0 || c == STR_LONGER )
return s;
s++;
}
return NULL;
}
/*
* Some user info printed to <stdout>.
*/
void print_strstat( void )
{
printf( "string processing:\n" );
printf( " upper-/lowercase: " );
if( case_sense )
printf( "strict\n" );
else
printf( "'ABC'='abc'\n" );
printf( " word delimiters: " );
switch( bordermode )
{
case 0:
printf( "'a,b c'='abc'\n" );
break;
case 1:
printf( "'a, b, c'='a,b c'\n" );
break;
case 2:
printf( "'a b c'='a b c'\n" );
break;
case 3:
printf( "strict\n" );
break;
}
}